package com.twang.stock.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.jayway.jsonpath.JsonPath;
import com.twang.stock.Entity.ShiShiData;
import com.twang.stock.common.http.HtmlTools;
import com.twang.stock.dto.ZdtData;
import com.twang.stock.email.SendmailService;
import com.twang.stock.entity.CompanyStock;
import com.twang.stock.entity.User;
import com.twang.stock.entity.ZhangTingJuJiao;
import com.twang.stock.entity.ZhangTingJuJiaoDto;
import com.twang.stock.mapper.CompanyStockMapper;
import com.twang.stock.mapper.UserMapper;
import com.twang.stock.mapper.ZhangTingJuJiaoMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.service.jinyan.CommonService;
import com.twang.stock.utils.date.HolidayCopy;
import com.twang.stock.utils.http.HttpStockUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ZhangTingjuJiaoService {

    public static String 涨停池_="1";
    public static String 冲刺涨停_="2";
    public static String 连扳池_="3";
    public static String 炸板池_="4";
    public static String 跌停池_="5";

    public static String ZHANGTINGJUJIAO_KEY="ZhangTingjuJiao_";

    public static String ZHANGTINGJUJIAO_KEY_DX_GD="ZHANGTINGJUJIAO_KEY_DX_GD";

    public static String ZHANGTINGJUJIAO_KEY_DX_HX="ZHANGTINGJUJIAO_KEY_DX_HX";

    //涨停封板率
    public static String ZHANGTINGJUJIAO_KEY_LIMIT_UP="ZHANGTINGJUJIAO_KEY_LIMIT_UP";

    //跌停数据
    public static String ZHANGTINGJUJIAO_KEY_LIMIT_DOWN="ZHANGTINGJUJIAO_KEY_LIMIT_DOWN";


    //涨跌停数据
    public static String QX_ZHANG_DIE_TING_DATA="QX_ZHANG_DIE_TING_DATA";


    @Autowired
    private SendmailService sendmailService;

    @Autowired
    private RedisUtil redisUtil;

    @Resource
    private ZhangTingJuJiaoMapper zhangTingJuJiaoMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private CompanyStockMapper companyStockMapper;


    @Autowired
    private CommonService commonService;


    public void 涨停聚焦(String date){
        try {
            ZdtData zdtData=new ZdtData();
            ZhangTingJuJiaoDto zhangTingJuJiaoDto = new ZhangTingJuJiaoDto();
            //涨停版
            String url = "https://data.10jqka.com.cn/dataapi/limit_up/limit_up_pool?page=1&limit=150&field=199112,10,9001,330323,330324,330325,9002,330329,133971,133970,1968584,3475914,9003,9004&filter=HS,GEM2STAR&order_field=330324&order_type=0&_=1697188532792&date=";
            zhangTingJuJiaoDto = 涨停聚焦执行(url, date, 涨停池_);
            insertDate(zhangTingJuJiaoDto, 涨停池_);
            zdtData.setZhangTingNum(zhangTingJuJiaoDto.getInfo().size());
            //冲刺涨停
            url = "https://data.10jqka.com.cn/dataapi/limit_up/limit_up?page=1&limit=50&field=199112,10,48,1968584,19,3475914,9003,9004&filter=HS,GEM2STAR&order_field=199112&order_type=0&_=1697276709844&date=";
            zhangTingJuJiaoDto = 涨停聚焦执行(url, date, 冲刺涨停_);
            insertDate(zhangTingJuJiaoDto, 冲刺涨停_);

            //连扳池
            url = "https://data.10jqka.com.cn/dataapi/limit_up/continuous_limit_pool?page=1&limit=50&field=199112,10,330329,330325,133971,133970,1968584,3475914,3541450,9004&filter=HS,GEM2STAR&order_field=330329&order_type=0&_=1697277852030&date=";
            zhangTingJuJiaoDto = 涨停聚焦执行(url, date, 连扳池_);
            insertDate(zhangTingJuJiaoDto, 连扳池_);

            //炸板池
            url = "https://data.10jqka.com.cn/dataapi/limit_up/open_limit_pool?page=1&limit=50&field=199112,9002,48,1968584,19,3475914,9003,10,9004&filter=HS,GEM2STAR&order_field=199112&order_type=0&_=1697276712736&date=";
            zhangTingJuJiaoDto = 涨停聚焦执行(url, date, 炸板池_);
            insertDate(zhangTingJuJiaoDto, 炸板池_);

            //跌停池
            url = "https://data.10jqka.com.cn/dataapi/limit_up/lower_limit_pool?page=1&limit=50&field=199112,10,330333,330334,1968584,3475914,9004&filter=HS,GEM2STAR&order_field=330334&order_type=0&_=1697299579125&date=";
            zhangTingJuJiaoDto = 涨停聚焦执行(url, date, 跌停池_);
            insertDate(zhangTingJuJiaoDto, 跌停池_);
            if(CollectionUtils.isNotEmpty(zhangTingJuJiaoDto.getInfo())){
                zdtData.setDieTingNum(zhangTingJuJiaoDto.getInfo().size());
            }

            //1、计算情绪反馈
            短线情绪高度();
            //2、趋势核心反馈
            趋势核心反馈();

            //判断涨跌停数量变化
            dieTingData(zdtData);

            redisUtil.set(ZHANGTINGJUJIAO_KEY_LIMIT_UP, JSONObject.toJSONString(zhangTingJuJiaoDto.getLimitUpCount()));

            redisUtil.set(ZHANGTINGJUJIAO_KEY_LIMIT_DOWN, JSONObject.toJSONString(zhangTingJuJiaoDto.getLimitDownCount()));



        } catch (Exception e) {
            log.info(">>>>> 涨停聚焦 date={} ERROR={} ", date,e);
        }
    }

    /**
     * 判断跌停数量
     * @param zdtData
     */
    public void dieTingData(ZdtData zdtData) {
        String key = QX_ZHANG_DIE_TING_DATA + ":" + HolidayCopy.getRealToday();
        Object object = redisUtil.get(key);
        if (null != object) {
            ZdtData zdtData1 = (ZdtData) object;
            String name = "";
            String message = "";
            if (zdtData.getDieTingNum() > zdtData1.getDieTingNum()) {
                int num = zdtData.getDieTingNum() - zdtData1.getDieTingNum();
                if (num > 0) {
                    name = String.format("【危】！！！跌停增加%s", num);
                    message = String.format("跌停数量增加：【%s】个！,     当前跌停数量：%s,  涨停数量：%s,   [前值：涨停：%s,跌停：%s]", num, zdtData.getDieTingNum(), zdtData.getZhangTingNum(), zdtData1.getZhangTingNum(), zdtData1.getDieTingNum());
                }
                if (zdtData.getDieTingNum() >= 10) {
                    name = String.format("危!!!马上空仓！");
                    message = String.format("当前跌停数量超过10，可能会引发短线流动性危机！", zdtData.getDieTingNum());

                }
                List<String> ids = Arrays.asList(commonService.getValue("warn_da_pan_wen_du").toString().split(","));
                for (String id : ids) {
                    User user = userMapper.selectByPrimaryKey(id);
                    if (null != user) {
                        log.info(">>>>>>>>>>>> start 跌停数量预警 user id ={} email={} ", id, user.getEmail());
                        sendmailService.sendMailWithEmail(message, name, name, user.getId());
                    }
                }
            }
        }
        redisUtil.set(key, zdtData, 60 * 60 * 8);
    }


    /**
     * 趋势核心反馈
     * @throws InterruptedException
     */
    private void 趋势核心反馈() throws InterruptedException {
        String 趋势核心反馈 = "";
        String[] codeList = commonService.getValue(CommonService.DX_QX_GD).split(",");
        List<ShiShiData> shiShiDataList = HtmlTools.getGpdatas(Lists.newArrayList(codeList));
        if (CollectionUtils.isNotEmpty(shiShiDataList)) {
            List 强正反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(4.5)) == 1).collect(Collectors.toList());
            if (强正反馈集合.size() == shiShiDataList.size()) {
                趋势核心反馈 = "强正反馈";
            } else {
                List 正反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(2)) == 1).collect(Collectors.toList());
                if (正反馈集合.size() == shiShiDataList.size()) {
                    趋势核心反馈 = "正反馈";
                } else {
                    List 强負反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(-5)) == -1).collect(Collectors.toList());
                    if (强負反馈集合.size() == shiShiDataList.size()) {
                        趋势核心反馈 = "强负反馈";
                    } else {
                        List 負反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(2)) == -1).collect(Collectors.toList());
                        if (負反馈集合.size() == shiShiDataList.size()) {
                            趋势核心反馈 = "负反馈";
                        }
                    }
                }
            }
        }
        if(StringUtils.isEmpty(趋势核心反馈)){
            BigDecimal avgAmount = shiShiDataList.stream().map(detail -> Optional.ofNullable(detail.getZhangdie()).orElse(BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(shiShiDataList.size())).setScale(2,BigDecimal.ROUND_HALF_UP);
            趋势核心反馈=avgAmount+"%";
        }
        redisUtil.set(ZHANGTINGJUJIAO_KEY_DX_HX, 趋势核心反馈);
    }

    private void insertDate(ZhangTingJuJiaoDto zhangTingJuJiaoDto,String type){
        List<ZhangTingJuJiao> info=zhangTingJuJiaoDto.getInfo();
        if(CollectionUtils.isNotEmpty(info)){
            ZhangTingJuJiao param = new ZhangTingJuJiao();
            param.setDate(info.get(0).getDate());
            param.setOrderType(info.get(0).getOrderType());
            zhangTingJuJiaoMapper.delete(param);
            info.stream().forEach(item-> {
                zhangTingJuJiaoMapper.insert(item);
            });
            //
            redisUtil.set(ZHANGTINGJUJIAO_KEY+type, JSONObject.toJSONString(info));
        }

    }

    /**
     * 短线情绪高度
     * @throws InterruptedException
     */
    private void 短线情绪高度() throws InterruptedException {
        String 短线情绪高度 = "";
        String[] codeList = commonService.getValue(CommonService.DX_QX_GD).split(",");
        List<ShiShiData> shiShiDataList = HtmlTools.getGpdatas(Lists.newArrayList(codeList));
        if (CollectionUtils.isNotEmpty(shiShiDataList)) {
            List 强正反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(4.5)) == 1).collect(Collectors.toList());
            if (强正反馈集合.size() == shiShiDataList.size()) {
                短线情绪高度 = "强正反馈";
            } else {
                List 正反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(2)) == 1).collect(Collectors.toList());
                if (正反馈集合.size() == shiShiDataList.size()) {
                    短线情绪高度 = "正反馈";
                } else {
                    List 强負反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(-5)) == -1).collect(Collectors.toList());
                    if (强負反馈集合.size() == shiShiDataList.size()) {
                        短线情绪高度 = "强负反馈";
                    } else {
                        List 負反馈集合 = shiShiDataList.stream().filter(p -> p.getZhangdie().compareTo(new BigDecimal(2)) == -1).collect(Collectors.toList());
                        if (負反馈集合.size() == shiShiDataList.size()) {
                            短线情绪高度 = "负反馈";
                        }
                    }
                }
            }
        }
        if(StringUtils.isEmpty(短线情绪高度)){
            BigDecimal avgAmount = shiShiDataList.stream().map(detail -> Optional.ofNullable(detail.getZhangdie()).orElse(BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(shiShiDataList.size())).setScale(2,BigDecimal.ROUND_HALF_UP);
            短线情绪高度=avgAmount+"%";
        }
        redisUtil.set(ZHANGTINGJUJIAO_KEY_DX_GD, 短线情绪高度);
    }


    /**
     * 涨停聚焦
     * @param url
     * @param date
     * @param type  1-涨停池，2-连板池，3-连板池
     * @return
     * @throws Exception
     */
    public  ZhangTingJuJiaoDto 涨停聚焦执行(String url, String date, String type) throws Exception {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        url = url + date;
        String result = HttpStockUtils.getHtmlStrByUrlUtf8(url);
        ZhangTingJuJiaoDto zhangTingJuJiaoDto=null;
        String str = JSONObject.toJSONString(JsonPath.read(result, "$.data"));
        if (StringUtils.isNotEmpty(str)) {
            zhangTingJuJiaoDto = JSONObject.parseObject(str, ZhangTingJuJiaoDto.class);
            if (null != zhangTingJuJiaoDto) {
                List<ZhangTingJuJiao> list = zhangTingJuJiaoDto.getInfo();
                if (CollectionUtils.isNotEmpty(list)) {
                    for (int i = list.size() - 1; i >= 0; i--) {
                        ZhangTingJuJiao zhangTingJuJiao = list.get(i);
                        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        if(StringUtils.isNotEmpty(zhangTingJuJiao.getFirstLimitUpTime())){
                            zhangTingJuJiao.setFirstLimitUpTime(sd.format(new Date(Long.valueOf(zhangTingJuJiao.getFirstLimitUpTime() + "000"))));
                        }
                        if(StringUtils.isNotEmpty(zhangTingJuJiao.getLastLimitUpTime())){
                            zhangTingJuJiao.setLastLimitUpTime(sd.format(new Date(Long.valueOf(zhangTingJuJiao.getLastLimitUpTime() + "000"))));
                        }
                        if(null!=zhangTingJuJiao.getCurrencyValue()){
                            zhangTingJuJiao.setCurrencyValue(zhangTingJuJiao.getCurrencyValue().setScale(6, BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getLimitUpSucRate()){
                            zhangTingJuJiao.setLimitUpSucRate(zhangTingJuJiao.getLimitUpSucRate().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getChangeRate()){
                            zhangTingJuJiao.setChangeRate(zhangTingJuJiao.getChangeRate().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getRiseRate()){
                            zhangTingJuJiao.setRiseRate(zhangTingJuJiao.getRiseRate().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getTurnoverRate()){
                            zhangTingJuJiao.setTurnoverRate(zhangTingJuJiao.getTurnoverRate().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getTurnover()){
                            zhangTingJuJiao.setTurnover(zhangTingJuJiao.getTurnover().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getOrderAmount()){
                            zhangTingJuJiao.setOrderAmount(zhangTingJuJiao.getOrderAmount().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        if(null!=zhangTingJuJiao.getLatest()){
                            zhangTingJuJiao.setLatest(zhangTingJuJiao.getLatest().setScale(6,BigDecimal.ROUND_HALF_UP));
                        }
                        zhangTingJuJiao.setDate(date);
                        zhangTingJuJiao.setOrderType(type);
                    }
                }
            }
        }
        log.info(">>>>> 涨停聚焦 type={} Response={} ", type, JSONObject.toJSONString(zhangTingJuJiaoDto));
        return zhangTingJuJiaoDto;
    }

}
